#ifndef _TYPESLOADER_H_
#define _TYPESLOADER_H_

namespace SEngine
{
    template<typename... T>
    struct TypesLoader {
        constexpr size_t Size() { 
            return sizeof...(T);
        }
        using Variant = std::variant<T...>;
        using VariantPtr = std::variant<T*...>;

        template<typename U>
        constexpr bool HasType() {
            int count = 0;
            ForeachType([&count](auto loader) {
                count += std::is_same_v<U, decltype(loader)::Type> ? 1 : 0;
            }, *this);
            return count != 0;
        } 
    };

    template<typename T>
    struct TypeLoader {
        using Type = T;
    };

    template<typename F, typename T, typename... Ts>
    constexpr void ForeachType(F && fn, TypesLoader<T, Ts...> loader) {
        fn(TypeLoader<T>());
        if constexpr (sizeof...(Ts) > 0) {
            ForeachType(std::forward<F>(fn), TypesLoader<Ts...>());
        }
    }

    #define TYPELOADER_TYPE(loader) decltype(loader)::Type

    
} // namespace SEngine


#endif